﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="RulesEngine"
    targetNamespace="http://cipl.codeplex.com.com/CIPlRule1.xsd"
    elementFormDefault="qualified"
    xmlns="http://cipl.codeplex.com.com/CIPlRule1.xsd"
    xmlns:mstns="http://cipl.codeplex.com.com/CIPlRule1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <!--======================================================================-->
  <!-- Top level action elements-->
  <xs:element name="Action" type="ActionType"/>
  <xs:element name="ConditionalAction" type="ConditionalActionType"/>
  <xs:element name="ActionSequence" type="ActionSequenceType"/>
  <!--======================================================================-->
  <!-- Top level value elements-->
  <xs:element name="LogicalExpression" type="LogicalExpressionType"/>
  <xs:element name="BooleanExpression" type="BooleanExpressionType"/>
  <xs:element name="ArithmeticExpression" type="ArithmeticExpressionType"/>
  <xs:element name="StringExpression" type="StringExpressionType"/>
  <xs:element name="DateTimeExpression" type="DateTimeExpressionType"/>
  <xs:element name="BooleanAtom" type="BooleanAtomType"/>
  <xs:element name="StringAtom" type="StringAtomType"/>
  <xs:element name="IntegerAtom" type="IntegerAtomType"/>
  <xs:element name="DecimalAtom" type="DecimalAtomType"/>
  <xs:element name="FloatAtom" type="FloatAtomType"/>
  <xs:element name="DateTimeAtom" type="DateTimeAtomType"/>
  <!--======================================================================-->
  <!-- Actions -->
  <xs:complexType name="ActionType">
    <xs:choice maxOccurs="3" minOccurs="0">
      <xs:element name="LogicalExpression" type="LogicalExpressionType"/>
      <xs:element name="BooleanExpression" type="BooleanExpressionType"/>
      <xs:element name="ArithmeticExpression" type="ArithmeticExpressionType"/>
      <xs:element name="StringExpression" type="StringExpressionType"/>
      <xs:element name="DateTimeExpression" type="DateTimeExpressionType"/>
      <xs:element name="BooleanAtom" type="BooleanAtomType"/>
      <xs:element name="StringAtom" type="StringAtomType"/>
      <xs:element name="IntegerAtom" type="IntegerAtomType"/>
      <xs:element name="DecimalAtom" type="DecimalAtomType"/>
      <xs:element name="FloatAtom" type="FloatAtomType"/>
      <xs:element name="DateTimeAtom" type="DateTimeAtomType"/>
    </xs:choice>
    <xs:attribute name="ActionOperator" type="ActionOperatorEnum"/>
  </xs:complexType>
  <xs:complexType name="ConditionalActionType">
    <xs:sequence>
      <xs:element name="Condition">
        <xs:complexType>
          <xs:choice maxOccurs="1">
            <xs:element name="LogicalExpression" type="LogicalExpressionType"/>
            <xs:element name="BooleanExpression" type="BooleanExpressionType"/>
            <xs:element name="BooleanAtom" type="BooleanAtomType"/>
          </xs:choice>
        </xs:complexType>
      </xs:element>
      <xs:sequence>
        <xs:element name="ThenAction" minOccurs="0">
          <xs:complexType>
            <xs:choice maxOccurs="1">
              <xs:element name="Action" type="ActionType"/>
              <xs:element name="ConditionalAction" type="ConditionalActionType"/>
              <xs:element name="ActionSequence" type="ActionSequenceType"/>
            </xs:choice>
          </xs:complexType>
        </xs:element>
        <xs:element name="ElseAction" minOccurs="0">
          <xs:complexType>
            <xs:choice maxOccurs="1">
              <xs:element name="Action" type="ActionType"/>
              <xs:element name="ConditionalAction" type="ConditionalActionType"/>
              <xs:element name="ActionSequence" type="ActionSequenceType"/>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ActionSequenceType">
    <xs:choice maxOccurs="unbounded">
      <xs:element name="Action" type="ActionType"/>
      <xs:element name="ConditionalAction" type="ConditionalActionType"/>
      <xs:element name="ActionSequence" type="ActionSequenceType"/>
    </xs:choice>
  </xs:complexType>
  <xs:complexType name="Value">
  </xs:complexType>
  <xs:simpleType name="ActionOperatorEnum">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ASSIGN"/>
      <xs:enumeration value="REMOVEFIELD"/>
      <xs:enumeration value="RELOCATE"/>
      <xs:enumeration value="RUN"/>
      <xs:enumeration value="CREATEITEM"/>
      <xs:enumeration value="ADDITEMMESSAGE"/>
      <xs:enumeration value="ADDPROPERTYMESSAGE"/>
      <xs:enumeration value="ADDMESSAGE"/>
    </xs:restriction>
  </xs:simpleType>
  <!--======================================================================-->
  <!-- Expressions -->
  <xs:complexType name="LogicalExpressionType">
    <xs:choice maxOccurs="2">
      <xs:element name="LogicalExpression" type="LogicalExpressionType"/>
      <xs:element name="BooleanExpression" type="BooleanExpressionType"/>
      <xs:element name="BooleanAtom" type="BooleanAtomType"/>
    </xs:choice>
    <xs:attribute name="Operator" type="LogicalOperatorType"/>
  </xs:complexType>
  <xs:simpleType name="LogicalOperatorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="AND"/>
      <xs:enumeration value="OR"/>
      <xs:enumeration value="NOT"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="BooleanExpressionType">
    <xs:choice maxOccurs="3">
      <xs:element name="LogicalExpression" type="LogicalExpressionType"/>
      <xs:element name="BooleanExpression" type="BooleanExpressionType"/>
      <xs:element name="ArithmeticExpression" type="ArithmeticExpressionType"/>
      <xs:element name="StringExpression" type="StringExpressionType"/>
      <xs:element name="DateTimeExpression" type="DateTimeExpressionType"/>
      <xs:element name="BooleanAtom" type="BooleanAtomType"/>
      <xs:element name="StringAtom" type="StringAtomType"/>
      <xs:element name="IntegerAtom" type="IntegerAtomType"/>
      <xs:element name="DecimalAtom" type="DecimalAtomType"/>
      <xs:element name="FloatAtom" type="FloatAtomType"/>
      <xs:element name="DateTimeAtom" type="DateTimeAtomType"/>
    </xs:choice>
    <xs:attribute name="Operator" type="BooleanOperatorType"/>
  </xs:complexType>
  <xs:simpleType name="BooleanOperatorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="EQL">
        <xs:annotation>
          <xs:documentation>Equals operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="NEQ">
        <xs:annotation>
          <xs:documentation>Not Equals operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="GTR">
        <xs:annotation>
          <xs:documentation>Greater than operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="LSS">
        <xs:annotation>
          <xs:documentation>Less than operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="GEQ">
        <xs:annotation>
          <xs:documentation>Greater than or equal operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="LEQ">
        <xs:annotation>
          <xs:documentation>Less than or equal operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="EXISTS">
        <xs:annotation>
          <xs:documentation>Exists operator - true if the contained CICl evaluates to at least one value - you should never use anything other than cic:forone as the CICl in an exists operator</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="CONTAINS">
        <xs:annotation>
          <xs:documentation>Contains operator - true if the target in the Right Atom is present in the string contained in the Left Atom -  the matching is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="CONTAINSATLEASTONE">
        <xs:annotation>
          <xs:documentation>Contains operator - true if at least one of the list of targets in the Right Atom is present in the string contained in the Left Atom -  the matching is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="CONTAINSALL">
        <xs:annotation>
          <xs:documentation>Contains operator - true if all of the list of targets in the Right Atom are present in the string contained in the Left Atom -  the matching is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="STARTSWITH">
        <xs:annotation>
          <xs:documentation>Starts with operator - applies only to strings - true if the Left Atom starts with the contents of the Right Atom - the match is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="ENDSWITH">
        <xs:annotation>
          <xs:documentation>Ends with operator - applies only to strings - true if the Left Atom ends with the contents of the Right Atom  - the match is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="LIKEMATCH">
        <xs:annotation>
          <xs:documentation>Like Match operator - applies only to strings - true if some part of the Left Atom matchs the pattern specified in the Right Atom</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="EXACTMATCH">
        <xs:annotation>
          <xs:documentation>Exact Match operator - applies only to strings - true if all of the Left Atom matchs the pattern specified in the Right Atom</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="HASAVALUE">
        <xs:annotation>
          <xs:documentation>Has a value operator - returns true if the right operand has a value - this is a unary operator the Left atom must not have a value</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="PRECISIONTEST">
        <xs:annotation>
          <xs:documentation>The precision test operator - the number of digits to the right of the decimal point in the left operand must be less than the number in the right operand</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="MAXLENGTHTEST">
        <xs:annotation>
          <xs:documentation>The max length test operator - the number of characters in the left operand must be less or equal to than the number in the right operand - if the left operand is a number any periood character ('.') will be ignored</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="MINLENGTHTEST">
        <xs:annotation>
          <xs:documentation>The min length test operator - the number of characters in the left operand must be greater than or equal to the number in the right operand - if the left operand is a number any periood character ('.') will be ignored</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="DOESNOTCONTAIN">
        <xs:annotation>
          <xs:documentation>Does not contain operator - true if the target in the Right Atom is not present in the string contained in the Left Atom -  the matching is case insensitive</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="VALIDURI">
        <xs:annotation>
          <xs:documentation>Valid URI operator - true if the target in the Right Atom is a valid URI -  uses the CLR Uri class to do the validate</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="VALIDISBN">
        <xs:annotation>
          <xs:documentation>
            Valid ISBN operator - true if the target in the Right Atom is a valid ISBN
            uses the following regular expression for teh format
            (?=[-0-9xX ]{13}$)(?:[0-9]+[- ]){3}[0-9]*[xX0-9]$
            uses the following formula for the check digit
            For each of the first 9 digits, multiply the digit by its position in
            the ISBN - so, multiply digit 1 by 1, digit 2 by 2, digit 3 by 3, and
            so on to digit 9 * 9. Add the lot of them up. Take the result mod 11.
            This gives you your last digit - with the caveat that if the result mod
            11 is 10, the last digit is X.
          </xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="VALIDUPC">
        <xs:annotation>
          <xs:documentation>Valid ISBN operator - true if the target in the Right Atom is a valid UPC</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="CONTAINSHTML">
        <xs:annotation>
          <xs:documentation>does not contain html operator - true if the target in the Right Atom does not contain any html elements</xs:documentation>
        </xs:annotation>
      </xs:enumeration>
      <xs:enumeration value="ALL">
        <xs:annotation>
          <xs:documentation>
            ALL operator - true if the given expression is true for all the given values. The first
            parameter must be a list of values, the second parameter must be a boolean expression.
            The variable 'each' can be used to access the current value which may be either a simple
            value or a compound value (for example each accesses the current simple value, each.Sku accesses
            the Sku property of the current value).
          </xs:documentation>
        </xs:annotation>
      </xs:enumeration>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="ArithmeticExpressionType">
    <xs:choice maxOccurs="3">
      <xs:element name="ArithmeticExpression" type="ArithmeticExpressionType"/>
      <xs:element name="IntegerAtom" type="IntegerAtomType"/>
      <xs:element name="FloatAtom" type="FloatAtomType"/>
      <xs:element name="DecimalAtom" type="DecimalAtomType"/>
    </xs:choice>
    <xs:attribute name="Operator" type="ArithmeticOperatorType"/>
  </xs:complexType>
  <xs:simpleType name="ArithmeticOperatorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="PLUS"/>
      <xs:enumeration value="MINUS"/>
      <xs:enumeration value="TIMES"/>
      <xs:enumeration value="DIVIDE"/>
      <xs:enumeration value="EXPON"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="StringExpressionType">
    <xs:choice maxOccurs="3">
      <xs:element name="StringExpression" type="StringExpressionType"/>
      <xs:element name="StringAtom" type="StringAtomType"/>
      <xs:element name="IntegerAtom" type="IntegerAtomType"/>
    </xs:choice>
    <xs:attribute name="Operator" type="StringOperatorType"/>
  </xs:complexType>
  <xs:simpleType name="StringOperatorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="CONCAT"/>
      <xs:enumeration value="REPLACE"/>
      <xs:enumeration value="SUBSTRING"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="DateTimeExpressionType">
    <xs:choice maxOccurs="3">
      <xs:element name="DateTimeExpression" type="DateTimeExpressionType"/>
      <xs:element name="DateTimeAtom" type="DateTimeAtomType"/>
    </xs:choice>
    <xs:attribute name="Operator" type="DateTimeOperatorType"/>
  </xs:complexType>
  <xs:simpleType name="DateTimeOperatorType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ADDYEARS"/>
      <xs:enumeration value="ADDMONTHS"/>
      <xs:enumeration value="ADDDAYS"/>
      <xs:enumeration value="ADDHOURS"/>
      <xs:enumeration value="ADDMINUTES"/>
    </xs:restriction>
  </xs:simpleType>
  <!--======================================================================-->
  <!-- Atoms -->
  <xs:simpleType name="AtomSourceEnum">
    <xs:restriction base="xs:string">
      <xs:enumeration value="literal"/>
      <xs:enumeration value="variable"/>
      <xs:enumeration value="parameter"/>
      <xs:enumeration value="namedValue"/>
      <xs:enumeration value="function"/>
      <xs:enumeration value="script"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="BooleanAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalBooleanType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="StringAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalStringType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="IntegerAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalIntegerType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="DecimalAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalDecimalType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="FloatAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalFloatType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="DateTimeAtomType">
    <xs:simpleContent>
      <xs:extension base="OptionalDateTimeType">
        <xs:attribute name="Name" type="xs:string"/>
        <xs:attribute name="AtomSource" type="AtomSourceEnum"/>
        <xs:anyAttribute namespace="http://cipl.codeplex.com.com/CICl1.xsd"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:simpleType name="EmptyStringType">
    <xs:restriction base="xs:string">
      <xs:maxLength value="0"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="OptionalBooleanType">
    <xs:union memberTypes="xs:boolean EmptyStringType"/>
  </xs:simpleType>
  <xs:simpleType name="OptionalStringType">
    <xs:union memberTypes="xs:string EmptyStringType"/>
  </xs:simpleType>
  <xs:simpleType name="OptionalIntegerType">
    <xs:union memberTypes="xs:integer EmptyStringType"/>
  </xs:simpleType>
  <xs:simpleType name="OptionalFloatType">
    <xs:union memberTypes="xs:double EmptyStringType"/>
  </xs:simpleType>
  <xs:simpleType name="OptionalDecimalType">
    <xs:union memberTypes="xs:decimal EmptyStringType"/>
  </xs:simpleType>
  <xs:simpleType name="OptionalDateTimeType">
    <xs:union memberTypes="xs:dateTime EmptyStringType"/>
  </xs:simpleType>
</xs:schema>
